/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.generator.template;

import cn.hutool.core.util.StrUtil;
import com.lambkit.util.FileKit;
import com.lambkit.util.Printer;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public abstract class TemplateEngine {
	
	/**
	 * 核心函数处理，自动生成代码, 批量处理，并生成文件
	 * @param templateModel
	 * @param filepathModel
	 */
	public void generate(Map<String, Object> templateModel, Map<String, Object> filepathModel, String outRootDir) {
		//Printer.print(this, "generator"("--------JFinal Class Template模板引擎处理开始-----------");
		if(filepathModel.size() < 1) {
			return;
		}

		String templateType = (String) filepathModel.get("type");
		String templatePath = (String) filepathModel.get("templatePath");
		String templateFilePath = (String) filepathModel.get("templateFilePath");

		String excludedTemplate = null;
		if(templateModel.get("excludedTemplate")!=null) {
			excludedTemplate = (String) templateModel.get("excludedTemplate");
		}

		if("class".equalsIgnoreCase(templateType) || "file".equalsIgnoreCase(templateType)) {
			String generatFilePath = (String) filepathModel.get("generatFilePath");
			String path = outRootDir + generatFilePath;
			if(generatFilePath.startsWith("file://")) {
				path = generatFilePath.substring(7);
			}
			String newPath = FileKit.processDir(templateModel, path);
			// 读取文件
			File filetmp = new File(newPath);
			try {
				FileKit.checkAndCreateParent(filetmp);
				FileWriter fw = new FileWriter(filetmp);
				//System.out.println("templatePath: " + templatePath);
				//System.out.println("templateFilePath: " + templateFilePath);
				if(checkExculedTemplate(templateFilePath, excludedTemplate)) {
					return;
				}
				// 模板转换并写文件
				fw.write(execute(templatePath, templateFilePath, templateType, templateModel));
				fw.flush();
				fw.close();
				showInfo(newPath);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			List<String> fileList = (List<String>) filepathModel.get("filelist");
			String folderpath = (String) filepathModel.get("folderpath");
			//println("文件夹 folderpath 为：", folderpath);
			for (String path : fileList) {
				if(checkExculedTemplate(path, excludedTemplate)) {
					continue;
				}
				//println("文件夹 path 为：", path);
				// 处理文件地址模板
				String newPath = FileKit.processDir(templateModel, path);
				//println("文件夹 newPath 为：", newPath);
				String newdir = newPath.replaceAll(FileKit.replacePath(folderpath), FileKit.replacePath(outRootDir));
				println("转换地址" + path + " 为：", newdir);
				// 读取文件
				File filetmp = new File(newdir);
				try {
					FileKit.checkAndCreateParent(filetmp);
					FileWriter fw = new FileWriter(filetmp);
					String fwpath = FileKit.replacePath(path);//.replace(folderpath, "");
					//println("所处理模板的地址为: ", templatePath + fwpath);
					//println("templatePath: ", templatePath);
					//println("fwpath: ", fwpath);
					String templateFolder = fwpath.substring(0, fwpath.indexOf(templatePath));
					String templateFile = fwpath.substring(fwpath.indexOf(templatePath));
//					// 模板转换并写文件
//					boolean flag = fwpath.length() > 2 && ":".equals(fwpath.substring(1, 2)) ? false : true;
//					if(flag) {
//						fwpath = templatePath + fwpath;
//					}
					//System.out.println("templateFolder: " + templateFolder);
					//System.out.println("templateFile: " + templateFile);
					fw.write(execute(templateFolder, templateFile, templateType, templateModel));
					fw.flush();
					fw.close();
					showInfo(newdir);
				} catch (IOException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		//Printer.print(this, "generator"("--------JFinal Class Template模板引擎处理完毕over!-----------");
	}
	
	/**
	 * 核心函数处理，自动生成代码, 单文件，并返回内容
	 * @return
	 */
	public abstract String execute(String templateFolder, String templatePath, String templateType, Map<String, Object> templateModel);

	public abstract String execute(String templateContent, Map<String, Object> templateModel);

	public String getFolderPath(String templateFilePath) {
		return templateFilePath.substring(0, templateFilePath.lastIndexOf("/"));
	}
	
	public String getFileName(String templateFilePath) {
		return templateFilePath.substring(templateFilePath.lastIndexOf("/") + 1);
	}
	/**
	 * 显示信息
	 * 
	 * @param info
	 */
	public void showInfo(String info) {
		Printer.print(this, "generator", "生成文件：" + info);
	}
	
	public void println(String title, String content) {
		Printer.print(this, "generator", title + content);
	}

	public boolean checkExculedTemplate(String template, String exculedTemplates) {
		if(exculedTemplates != null && !"".equals(exculedTemplates)) {
			String[] exculeds = exculedTemplates.split(",");
			for(String exculed : exculeds) {
				if(StrUtil.isBlank(exculed)) {
					continue;
				}
				if(template.indexOf(exculed.trim()) > -1) {
					return true;
				}
			}
		}
		return false;
	}
}
